package cn.dqy.gotanserver.web.ws;

import cn.dqy.gotanserver.dto.ChannelInfo;
import cn.dqy.gotanserver.service.CoreServer;
import cn.dqy.gotanserver.support.SmsSupport;
import cn.dqy.gotanserver.support.context.SpringContextSupport;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

@Component
@ServerEndpoint(value = "/websocket/{key}")
public class CameraWs {

    static Logger logger = LoggerFactory.getLogger(CameraWs.class);

    static CopyOnWriteArrayList<CameraWs> cameraWsList=new CopyOnWriteArrayList<>();
    static Map<String, Session> sessionPool= new ConcurrentHashMap<>();

    CoreServer coreServer;

    public CameraWs(){
        logger.info("new WS");
        this.coreServer = SpringContextSupport.getContext().getBean(CoreServer.class);
    }

    Session session;
    String key;
    @OnOpen
    public void onOpen(Session session,@PathParam(value = "key") String key){
        ChannelInfo channelInfo = coreServer.getChannelMap().get(key);
        if(null==channelInfo){
            logger.error("【websocket消息】错误得连接...，key={}",key);
            return;
        }
        this.key=key;
        this.session=session;
        logger.info("【websocket消息】新的webSocket连接到来,key={}",key);
        sessionPool.put(key,session);
    }

    @OnMessage
    public void onMessage(String msg){
        logger.info("【websocket消息】 收到客户端消息 msg={}",msg);
        Queue<String> picQueue = coreServer.getChannelMap().get(key).getPicQueue();
        LinkedBlockingQueue<String> queue= (LinkedBlockingQueue) picQueue;
        try {
            String poll = queue.poll(60, TimeUnit.SECONDS);
            byte[] bytes = FileUtils.readFileToByteArray(new File(poll));
            wsSend(key,bytes);
            FileUtils.delete(new File(poll));
        } catch (InterruptedException e) {
            logger.info("队列弹出超时");
            e.printStackTrace();
        }catch (IOException e){
            logger.info("读取文件出错");
            e.printStackTrace();
        }
    }

    @OnClose
    public void onClose() {
        logger.info("【websocket消息】连接断开，总数为:"+sessionPool.keySet().size());

        //发送关闭摄像机指令
        coreServer.closeCamera(key);
        //清空摄像机帧队列
        clsChannelQueue(key);
    }

    public void wsSend(String key,byte[] data){
        Session session = sessionPool.get(key);
        if(session==null){
            logger.error("【websocket消息】 {} session 不存在,不能发送",session);
            return;
        }
        ByteBuffer bf=ByteBuffer.wrap(data);
        session.getAsyncRemote().sendBinary(bf);

    }

    public void clsChannelQueue(String key){
        ChannelInfo channelInfo = coreServer.getChannelMap().get(key);
        if(channelInfo==null) return;
        Queue<String> picQueue = channelInfo.getPicQueue();
        logger.info("清空队列，需要清除 {} 帧",picQueue.size());
        while (!picQueue.isEmpty()){
            String poll = picQueue.poll();
            try {
                FileUtils.delete(new File(poll));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}
